package com.ytf.core.web.application;

import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.ytf.core.web.pojo.converter.UserConverter;
import com.ytf.core.web.pojo.dto.UserDto;
import com.ytf.core.web.pojo.model.User;
import com.ytf.core.web.pojo.model.UserRole;
import com.ytf.core.web.pojo.vo.RoleVo;
import com.ytf.core.web.pojo.vo.UserVo;
import com.ytf.core.web.service.IRoleService;
import com.ytf.core.web.service.IUserRoleService;
import com.ytf.core.web.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author YTF
 * @className UserAppService
 * @date 2025/5/21 14:44
 * @description 用户应用层
 */
@Service
public class UserAppService {

    @Autowired
    private IUserService iUserService;
    @Autowired
    private IRoleService iRoleService;
    @Autowired
    private RoleAppService roleAppService;
    @Autowired
    private IUserRoleService iUserRoleService;

    @Transactional(rollbackFor = Exception.class)
    public Boolean insert(UserDto userDto) {
        // 1.查询角色是否存在
        List<Long> roleIds = userDto.getRoleIds().stream().map(Long::valueOf).toList();
        Boolean existsByIds = iRoleService.existsByIds(roleIds);
        Assert.isTrue(existsByIds, "角色不存在请重新选择");
        // 2.新增用户
        User user = UserConverter.INSTANCE.userDtoToUser(userDto);
        boolean save = iUserService.save(user);
        Assert.isTrue(save, "新增失败");
        // 3.新增用户角色关联
        List<UserRole> userRoleList = roleIds.stream().map(i -> {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(i);
            return userRole;
        }).collect(Collectors.toList());
        return iUserRoleService.saveBatch(userRoleList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) {
        // 1.删除用户
        boolean removeById = iUserService.removeById(id);
        Assert.isTrue(removeById, "删除用户失败");
        // 2.删除用户角色关联
        Boolean aBoolean = iUserRoleService.removeByUserId(id);
        Assert.isTrue(aBoolean, "删除用户角色关联失败");
    }

    public UserVo getById(Long id) {
        // 1.查询用户
        User byId = iUserService.getById(id);
        Assert.notNull(byId, "查询用户不存在");
        // 2.查询关联角色id列表
        List<Long> roleIdByUserId = iUserRoleService.listRoleIdByUserId(id);
        Assert.notNull(roleIdByUserId, "查询角色没有关联权限");
        // 3.查询角色
        List<RoleVo> roleVos = roleIdByUserId.stream().map(i->roleAppService.getById(i)).toList();
        // 4.组装数据
        UserVo userVo = UserConverter.INSTANCE.userToUserVo(byId);
        userVo.setRoleVos(roleVos);
        return userVo;
    }

    public UserVo getByUsername(String username) {
        // 1.查询用户
        User user = iUserService.getByUsername(username);
        Assert.notNull(user, "查询用户不存在");
        // 2.查询关联角色id列表
        List<Long> roleIdByUserId = iUserRoleService.listRoleIdByUserId(user.getId());
        Assert.notNull(roleIdByUserId, "查询角色没有关联权限");
        // 3.查询角色
        List<RoleVo> roleVos = roleIdByUserId.stream().map(i->roleAppService.getById(i)).toList();
        // 4.组装数据
        UserVo userVo = UserConverter.INSTANCE.userToUserVo(user);
        userVo.setRoleVos(roleVos);
        return userVo;
    }

    public UserVo getByMobile(String mobile) {
        // 1.查询用户
        User user = iUserService.getByMobile(mobile);
        Assert.notNull(user, "查询用户不存在");
        // 2.查询关联角色id列表
        List<Long> roleIdByUserId = iUserRoleService.listRoleIdByUserId(user.getId());
        Assert.notNull(roleIdByUserId, "查询角色没有关联权限");
        // 3.查询角色
        List<RoleVo> roleVos = roleIdByUserId.stream().map(i->roleAppService.getById(i)).toList();
        // 4.组装数据
        UserVo userVo = UserConverter.INSTANCE.userToUserVo(user);
        userVo.setRoleVos(roleVos);
        return userVo;
    }

    public UserVo getByEmail(String email) {
        // 1.查询用户
        User user = iUserService.getByEmail(email);
        Assert.notNull(user, "查询用户不存在");
        // 2.查询关联角色id列表
        List<Long> roleIdByUserId = iUserRoleService.listRoleIdByUserId(user.getId());
        Assert.notNull(roleIdByUserId, "查询角色没有关联权限");
        // 3.查询角色
        List<RoleVo> roleVos = roleIdByUserId.stream().map(i->roleAppService.getById(i)).toList();
        // 4.组装数据
        UserVo userVo = UserConverter.INSTANCE.userToUserVo(user);
        userVo.setRoleVos(roleVos);
        return userVo;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean updateById(Long id, UserDto userDto) {
        // 1.查询用户是否存在
        Boolean existsById = iUserService.existsById(id);
        Assert.isTrue(existsById, "用户查询不存在");
        User user = UserConverter.INSTANCE.userDtoToUser(userDto);
        user.setId(id);
        // 2,修改用户
        boolean updateById = iUserService.updateById(user);
        Assert.isTrue(updateById, "用户修改失败");
        // 3.查询关联权限id列表
        List<Long> listRoleIdByUserId = iUserRoleService.listRoleIdByUserId(id);
        // 4.计算需要删除和添加的权限
        List<Long> newRoleIds = userDto.getRoleIds().stream().map(Long::valueOf).collect(Collectors.toList());
        Set<Long> commonElements = listRoleIdByUserId.parallelStream().filter(newRoleIds::contains).collect(Collectors.toSet());

        listRoleIdByUserId.removeAll(commonElements); // 删除
        newRoleIds.removeAll(commonElements); // 新增

        // 5.执行更新
        if (!listRoleIdByUserId.isEmpty()) {
            Boolean aBoolean = iUserRoleService.removeByUserIdAndRoleId(user.getId(), listRoleIdByUserId);
            Assert.isTrue(aBoolean, "删除用户角色关联失败");
        }

        if (!newRoleIds.isEmpty()) {
            // 3.新增用户角色关联
            List<UserRole> userRoleList = newRoleIds.stream().map(i -> {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(i);
                return userRole;
            }).collect(Collectors.toList());
            boolean saveBatch = iUserRoleService.saveBatch(userRoleList);
            Assert.isTrue(saveBatch, "新增用户角色关联失败");
        }
        return true;
    }
}
